﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using ERF;
using FirstPerson.Gametypes;
using ERF.Menu;

namespace FirstPerson.States
{
    class HostState : State
    {
        /// <summary>
        /// Singleton instance
        /// </summary>
        private static HostState instance;

        /// <summary>
        /// Get an instance of this state.
        /// </summary>
        /// <param name="machine">the state machine that this state should belong to.</param>
        /// <returns></returns>
        public static HostState GetInstance(StateMachine machine)
        {
            if (instance == null)
                instance = new HostState(machine);

            return instance;
        }

        private MenuList maps, gameTypes, killLimit, timeLimit;
        private MenuManager menuManager;
        private GameTime currentTime;
        private Menu menu;

        /// <summary>
        /// Constructor of HostState
        /// </summary>
        /// /// <summary>
        /// <param name="machine">the state machine that this state should belong to.</param>
        /// <returns></returns>
        private HostState(StateMachine machine)
            : base(machine)
        {
            this.menuManager = MenuManager.GetInstance(this.machine.CurrentGame);

            menu = new Menu("Host Game");
            menu.MenuItems.Add(new MenuItem("Back", this.BackToStartMenu));

            maps = new MenuList("Map", menu, menu);
            maps.MenuItems.Add(new MenuValueItem("The maze of doom", "maze", menu));
            maps.MenuItems.Add(new MenuValueItem("Hills of death", "hills", menu));
            maps.SelectedItem = maps.MenuItems[0];
            menu.MenuItems.Add(maps);

            gameTypes = new MenuList("GameType", menu, menu);
            gameTypes.MenuItems.Add(new MenuValueItem("Deathmatch", GameTypeNumber.DeathMatch, menu));
            gameTypes.MenuItems.Add(new MenuValueItem("Ghostmatch", GameTypeNumber.GhostMatch, menu));
            gameTypes.SelectedItem = gameTypes.MenuItems[0];
            menu.MenuItems.Add(gameTypes);

            timeLimit = new MenuList("Time limit", menu, menu);
            timeLimit.MenuItems.Add(new MenuValueItem("3", 3, menu));
            timeLimit.MenuItems.Add(new MenuValueItem("5", 5, menu));
            timeLimit.MenuItems.Add(new MenuValueItem("10", 10, menu));
            timeLimit.MenuItems.Add(new MenuValueItem("15", 15, menu));
            timeLimit.MenuItems.Add(new MenuValueItem("20", 20, menu));
            timeLimit.MenuItems.Add(new MenuValueItem("30", 30, menu));
            timeLimit.MenuItems.Add(new MenuValueItem("60", 60, menu));
            timeLimit.SelectedItem = timeLimit.MenuItems[2];
            menu.MenuItems.Add(timeLimit);

            killLimit = new MenuList("Kill limit", menu, menu);
            killLimit.MenuItems.Add(new MenuValueItem("5", 5, menu));
            killLimit.MenuItems.Add(new MenuValueItem("10", 10, menu));
            killLimit.MenuItems.Add(new MenuValueItem("15", 15, menu));
            killLimit.MenuItems.Add(new MenuValueItem("20", 20, menu));
            killLimit.MenuItems.Add(new MenuValueItem("25", 25, menu));
            killLimit.MenuItems.Add(new MenuValueItem("50", 50, menu));
            killLimit.MenuItems.Add(new MenuValueItem("100", 100, menu));
            killLimit.SelectedItem = killLimit.MenuItems[3];
            menu.MenuItems.Add(killLimit);

            menu.MenuItems.Add(new MenuItem("Host Game", HostGame));
            menu.SelectedIndex = 0;
        }

        public override void Initialize()
        {
            menuManager.Menu = menu;
        }

        private void BackToStartMenu()
        {
            machine.CurrentState = StartMenuState.GetInstance(machine);
        }

        private void HostGame()
        {
            /*
             * checks if there are a player signed in
             */
            if (Gamer.SignedInGamers.Count > 0)
            {
                PlayingState playingState = PlayingState.GetInstance(machine);

                MenuValueItem mapItem = (MenuValueItem)maps.SelectedItem;
                MenuValueItem gameTypeItem = (MenuValueItem)gameTypes.SelectedItem;
                GameTypeNumber gameTypeNumber = (GameTypeNumber)gameTypeItem.Value;

                MenuValueItem killLimitItem = (MenuValueItem)killLimit.SelectedItem;
                MenuValueItem timeLimitItem = (MenuValueItem)timeLimit.SelectedItem;

                GameData gameData = new GameData();
                gameData.startTime = currentTime.TotalRealTime.TotalSeconds;
                gameData.randomSeed = new Random().Next(10000);
                gameData.mapName = (String)mapItem.Value;
                gameData.gameTypeNumber = gameTypeNumber;
                gameData.killLimit = (short)((int)killLimitItem.Value);
                gameData.timeLimit = (short)((int)timeLimitItem.Value * 60);

                machine.CurrentState = playingState;
                machine.CurrentGame.NetworkHandler.HostGame(NetworkSessionType.SystemLink, 1, 8);

                menuManager.Visible = false;

                playingState.initMatch(gameData);
            }
        }

        /// <summary>
        /// Begin PlayingState and hosting the game
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Update(GameTime gameTime)
        {
            currentTime = gameTime;

            if (Gamer.SignedInGamers.Count == 0 && !Guide.IsVisible)
            {
                Guide.ShowSignIn(1, false);
            }

            if (input.IsButtonReleased("MENU_DOWN"))
            {
                menuManager.Menu.SelectNext();
            }

            if (input.IsButtonReleased("MENU_UP"))
            {
                menuManager.Menu.SelectPrevious();
            }

            if (input.IsButtonReleased("MENU_SELECT"))
            {
                menuManager.Menu.Submit();
            }

            if (input.IsButtonReleased("MENU_BACK"))
            {
                if (menuManager.Menu.ParentList != null)
                    menuManager.Menu.Back();
                else
                    BackToStartMenu();
            }
        }
    }
}
